package com.googlecode.jpocketmod.templates.pages;

import com.googlecode.jpocketmod.ApplicationProperties;
import java.awt.Image;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

/**
 *
 * @author David Sosby
 */
public class PageManager {
	private static PageManager instance = null;
	
	private Map<String,PocketModPage> pagesDatabase = new HashMap<String,PocketModPage>();
	private File pagesFolder;
	
	private PageManager()  {
		pagesFolder = new File(ApplicationProperties.getInstance().getProperty("Settings.PageFolder"));
		if ( !pagesFolder.exists() )  {
			if ( !pagesFolder.mkdirs() )  {
				//TODO: Dialog saying the pages folder could not be created
				System.err.println("Could not create pages folder: " + pagesFolder);
			}
		}
		
		loadPages();
	}
	
	public static PageManager getInstance()  {		
		if ( instance == null )  {
			synchronized(PageManager.class)  {
				if ( instance == null )  {
					instance = new PageManager();
				}
			}
		}
		
		return instance;	
	}
	
	public Image getPocketModPageImage(PocketModPageInstance pageInstance) throws Exception  {
		String requestedPageName = pageInstance.getPageName();
		
		if ( !pagesDatabase.containsKey(requestedPageName) )  {
			throw new Exception("Requested Page " + requestedPageName + " was not found in the local database.");
		}
		
		PocketModPage page = pagesDatabase.get(requestedPageName);
		return page.getImage(pageInstance.getUsersOptions());
	}
	
	private void addPage(PocketModPage page)  {
		if ( !pagesDatabase.containsKey(page.getName()) )  {
			pagesDatabase.put(page.getName(), page);
		}
	}
	
	private void loadPages()  {
		if ( pagesFolder.exists() )  {
			File[] pageFiles = pagesFolder.listFiles(new PocketModPageFilter());
			for ( int i=0 ; i<pageFiles.length ; i++ )  {
				FileInputStream fis = null;
				ObjectInputStream ois = null;

				try  {
					fis = new FileInputStream(pageFiles[i]);
					ois = new ObjectInputStream(fis);

					PocketModPage toAdd = (PocketModPage) ois.readObject();
					addPage(toAdd);
				}
				catch (Exception ex)  {
					//TODO: Dialog saying couldn't read page file
				}
				finally  {
					if ( fis != null )		try { fis.close(); } catch(Exception ex) {}
					if ( ois != null ) 		try { ois.close(); } catch(Exception ex) {}
				}
			}
		}
		else  {
			//TODO: Dialog saying can't find the Page folder
		}
	}
	
	public void addNewPage(PocketModPage newPage) throws Exception  {
		if ( pagesDatabase.containsKey(newPage.getName()) )  {
			throw new Exception("Database already contains Page named " + newPage.getName());
		}
		
		FileOutputStream ops = null;
		File saveFile = new File(pagesFolder + 
								 File.separator +
								 newPage.getName() + PocketModPageFilter.getExtension());
		
		if ( saveFile.exists() ) throw new Exception("Storage Area already contains Page named " + newPage.getName());
		
		try  {
			ops = new FileOutputStream(saveFile);
			ObjectOutputStream out = new ObjectOutputStream(ops);
			out.writeObject(newPage);
			out.close();
		}
		catch (Exception ex)  {
			throw ex;
		}
		finally {
			if ( ops != null )
				try  {  ops.close();  } catch(Exception ex) {}
		}
		
		addPage(newPage);
	}
	
	public Set<String> getAvailableCategories()  {
		Set<String> availableCategories = new TreeSet<String>();
		
		Iterator<Map.Entry<String,PocketModPage>> pagesItr = pagesDatabase.entrySet().iterator();
		while ( pagesItr.hasNext() )  {
			String category = pagesItr.next().getValue().getCategory();
			if ( category == null )  category = "";
			availableCategories.add(category);
		}
		
		return availableCategories;
	}
}

class PocketModPageFilter implements FileFilter  {
	private static String extension = ".pmp";
	
	public static String getExtension()  {  return extension;  }
	
	public boolean accept(File pathname) {
		return pathname.getName().toLowerCase().endsWith(extension);
	}
}
